package com.deer.wms.system.manage.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deer.wms.project.root.core.result.CommonCode;
import com.deer.wms.project.root.core.result.Result;
import com.deer.wms.project.root.core.service.QueryCriteria;
import com.deer.wms.project.root.exception.ServiceException;
import com.deer.wms.project.root.util.DateUtils;
import com.deer.wms.project.root.util.RedisUtil;
import com.deer.wms.project.root.util.StringUtils;
import com.deer.wms.system.manage.dao.AreaUserMapper;
import com.deer.wms.system.manage.dao.CellLedMapper;
import com.deer.wms.system.manage.model.CellLed;
import com.deer.wms.system.manage.model.ware.AreaUser;
import com.deer.wms.system.manage.service.AreaUserService;
import com.deer.wms.system.manage.service.CellLedService;
import com.deer.wms.system.manage.test.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* @author luowe
* @description 针对表【area_user(用户仓库表)】的数据库操作Service实现
* @createDate 2022-06-08 18:19:31
*/
@Service
public class CellLedServiceImpl extends ServiceImpl<CellLedMapper, CellLed>
    implements CellLedService{



    @Autowired
    private CellLedMapper cellLedMapper;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    public List<CellLed> findCellLed(List<String> cellCodes) {
        return cellLedMapper.findByCellCodeList(cellCodes);
    }

    @Override
    public void update(CellLed cellLed) {
        if (ObjectUtil.isNotEmpty(cellLed)){
            String cellCode = cellLed.getCellCode();
            //查询所有cellCode
            List<String> allCellCode = this.findAllCellCode();
            allCellCode.remove(cellCode);
            boolean contains = allCellCode.contains(cellCode);
            if (contains){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"该货位已绑定灯位");
            }
            //查询此ip下的灯位是否被绑定
            List<Integer> allLedId = this.findAllLedId(cellLed.getIp());
            allLedId.remove(cellLed.getLedId());
            boolean contains1 = allLedId.contains(cellLed.getLedId());
            if (contains1){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"此ip下灯位已被绑定");
            }
            this.updateById(cellLed);
        }
    }

    @Override
    public void add(CellLed cellLed) {
        if (ObjectUtil.isNotEmpty(cellLed)){
            String cellCode = cellLed.getCellCode();
            //查询所有cellCode
            List<String> allCellCode = this.findAllCellCode();
            boolean contains = allCellCode.contains(cellCode);
            if (contains){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"该货位已绑定灯位");
            }
            //查询此ip下的灯位是否被绑定
            List<Integer> allLedId = this.findAllLedId(cellLed.getIp());
            boolean contains1 = allLedId.contains(cellLed.getLedId());
            if (contains1){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"此ip下灯位已被绑定");
            }
            this.save(cellLed);
        }
    }

    @Override
    public List<CellLed> findList(QueryCriteria queryCriteria) {
        return baseMapper.findList(queryCriteria);
    }

    @Override
    public void delete(String ids) {
        if (StringUtils.isEmpty(ids)){
            throw new ServiceException(CommonCode.SYSTEM_ERROR,"id为空");
        }
        List<String> list = Stream.of(ids.split(",")).collect(Collectors.toList());
        baseMapper.deleted(list);
    }


    @Value("${prj.name}")
    private String prjName;
    /**
     * 通过仓库编码集合批量控制灯光
     * @param cellCodes 仓库编码
     * @param color 颜色
     * @param time  时长(s)
     * @param lighttype 亮----1  灭----0
     * @return
     */
    @Override
    public Result ledControl(List<String> cellCodes, String color, Long time, Integer lighttype) {
        if (ObjectUtil.notEqual("zp", prjName)) {
            return null;
        }
        ValueOperations valueOperations = redisUtil.getValueOperations();
        //返回对象
        Result<Object> result = new Result<>();
        try {
            if (ObjectUtil.isEmpty(cellCodes)){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"编码为空");
            }
            if (StringUtils.isEmpty(color)){
                //红色
                color = "1";
            }
            if (ObjectUtil.isEmpty(time)){
                //20s
                time = 20L;
            }
            if (ObjectUtil.isEmpty(lighttype)){
                //亮灯
                lighttype = 1;
            }
            List<CellLed> cellLedList = findCellLed(cellCodes);
            if (ObjectUtil.isEmpty(cellLedList)){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"未找到设备");
            }
            //设备mac地址
            String mac = "";
            //不在线的ip地址集合
            List<String> ipList = new ArrayList<>();
            Map<String, List<CellLed>> groupByIpMap = cellLedList.stream().collect(Collectors.groupingBy(CellLed::getIp));
            Set<String> ips = groupByIpMap.keySet();
            for (String ip : ips) {
                //从缓存中查询设备是否在线
//                Object ipMac = valueOperations.get(ip);
//                if (ObjectUtil.isEmpty(ipMac)){
//                    ipList.add(ip);
//                    continue;
//                }
                List<CellLed> cellLeds = groupByIpMap.get(ip);
                List<LedsMsgDto> ledsMsgDtos = new ArrayList<>();
                LedControlDto ledControlDto = new LedControlDto();
                if (ObjectUtil.isNotEmpty(cellLedList)) {
                    mac = cellLeds.get(0).getMac();
                    for (CellLed cellLed : cellLeds) {
                        LedsMsgDto ledsMsgDto = new LedsMsgDto();
                        ledsMsgDto.setColor(color);
                        ledsMsgDto.setId(cellLed.getLedId());
                        ledsMsgDto.setTimes(time);
                        ledsMsgDto.setLighttype(lighttype);
                        ledsMsgDtos.add(ledsMsgDto);
                    }
                }
                ledControlDto.setLedsmsg(ledsMsgDtos);
                ledControlDto.setMac(mac);
                //调用亮灯设备
                JsonResult jsonResult = LedUtils.ledControl(ledControlDto, ip);
                //调用失败的也加入不在线ip
                if (!jsonResult.getResult()){
                    ipList.add(ip);
                }
            }
            //不在线的设备提示
//            if (ObjectUtil.isNotEmpty(ipList)){
//                throw new ServiceException(CommonCode.SYSTEM_ERROR,"不在线设备ip"+ipList.toString());
//            }
            result.setCode(CommonCode.SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(CommonCode.SYSTEM_ERROR);
            result.setMessage(e.getMessage());
            return result;
        }
        return result;
    }

    /**
     * 接收设备心跳接口
     * @return
     */
    @Override
    public void heartbeat(HttpServletRequest request, HeartbeatDto heartbeatDto) {
        String ipAddr = IpUtil.getIpAddr(request);
        ValueOperations valueOperations = redisUtil.getValueOperations();
        //测试为70s一次
        valueOperations.set(heartbeatDto.getIp(),heartbeatDto.getMac(),70, TimeUnit.SECONDS);
        System.out.println(DateUtils.getNowDateTimeString3());
    }

    /**
     * 给设备设置心跳接口地址
     * @param ip 设备的ip地址
     * @return
     */
    @Override
    public Result setServerIp(String ip) {
        Result<Object> result = new Result<>();
        try{
            if (StringUtils.isEmpty(ip)){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"地址不能为空");
            }
            JsonResult jsonResult = LedUtils.setServerIp(ip);
            if (!jsonResult.getResult()){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"设置失败,请检查设备连接,当前设备ip:"+ip);
            }
        }catch (Exception e){
            e.printStackTrace();
            result.setCode(CommonCode.SYSTEM_ERROR);
            result.setMessage(e.getMessage());
            return result;
        }
        return result;
    }

    /**
     * 七彩循环全亮(检查)
     * @param ip 设备的ip地址
     * @return
     */
    @Override
    public Result ledcheck(String ip) {
        Result<Object> result = new Result<>();
        try{
            if (StringUtils.isEmpty(ip)){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"地址不能为空");
            }
            ValueOperations valueOperations = redisUtil.getValueOperations();
            Object mac = valueOperations.get(ip);
            if (ObjectUtil.isEmpty(mac)){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"设备不在线");
            }
            JsonResult jsonResult = LedUtils.ledCheck((String) mac,ip);
            if (!jsonResult.getResult()){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"设置失败,请检查设备连接,当前设备ip:"+ip);
            }
        }catch (Exception e){
            e.printStackTrace();
            result.setCode(CommonCode.SYSTEM_ERROR);
            result.setMessage(e.getMessage());
            return result;
        }
        return result;
    }


    /**
     * 设置料架左右分隔数
     * @param ip 设备的ip地址
     * @num 分隔数
     * @return
     */
    @Override
    public Result setmidnum(String ip, Integer num) {
        Result<Object> result = new Result<>();
        try{
            if (StringUtils.isEmpty(ip)){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"地址不能为空");
            }
            if (ObjectUtil.isEmpty(num)){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"左右分隔数不能为空");
            }
            ValueOperations valueOperations = redisUtil.getValueOperations();
            Object mac = valueOperations.get(ip);
            if (ObjectUtil.isEmpty(mac)){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"设备不在线");
            }
            //传输对象
            SetMidNumDto setMidNumDto = new SetMidNumDto();
            setMidNumDto.setMac((String) mac);
            setMidNumDto.setNum(num);
            //设置料架左右分隔数
            JsonResult jsonResult = LedUtils.setMidNum(setMidNumDto,ip);
            if (!jsonResult.getResult()){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"设置失败,请检查设备连接,当前设备ip:"+ip);
            }
        }catch (Exception e){
            e.printStackTrace();
            result.setCode(CommonCode.SYSTEM_ERROR);
            result.setMessage(e.getMessage());
            return result;
        }
        return result;
    }

    /**
     * 设置料架库位总数
     * @param ip 设备的ip地址
     * @return
     */
    @Override
    public Result settotalnum(String ip, Integer num) {
        Result<Object> result = new Result<>();
        try{
            if (StringUtils.isEmpty(ip)){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"地址不能为空");
            }
            if (ObjectUtil.isEmpty(num)){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"左右分隔数不能为空");
            }
            ValueOperations valueOperations = redisUtil.getValueOperations();
            Object mac = valueOperations.get(ip);
            if (ObjectUtil.isEmpty(mac)){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"设备不在线");
            }
            //传输对象
            SetMidNumDto setMidNumDto = new SetMidNumDto();
            setMidNumDto.setMac((String) mac);
            setMidNumDto.setNum(num);
            JsonResult jsonResult = LedUtils.setTotalNum(setMidNumDto,ip);
            if (!jsonResult.getResult()){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"设置失败,请检查设备连接,当前设备ip:"+ip);
            }
        }catch (Exception e){
            e.printStackTrace();
            result.setCode(CommonCode.SYSTEM_ERROR);
            result.setMessage(e.getMessage());
            return result;
        }
        return result;
    }

    /**
     * 全亮/灭
     * @param ip 设备的ip地址
     * @return
     */
    @Override
    public Result allledcontrol(AllLedControlDto allLedControlDto, String ip) {
        Result<Object> result = new Result<>();
        try{
            if (StringUtils.isEmpty(ip)){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"地址不能为空");
            }
            ValueOperations valueOperations = redisUtil.getValueOperations();
            Object mac = valueOperations.get(ip);
            if (ObjectUtil.isEmpty(mac)){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"设备不在线");
            }
            allLedControlDto.setMac((String) mac);
            JsonResult jsonResult = LedUtils.allLedControl(allLedControlDto,ip);
            if (!jsonResult.getResult()){
                throw new ServiceException(CommonCode.SYSTEM_ERROR,"设置失败,请检查设备连接,当前设备ip:"+ip);
            }
        }catch (Exception e){
            e.printStackTrace();
            result.setCode(CommonCode.SYSTEM_ERROR);
            result.setMessage(e.getMessage());
            return result;
        }
        return result;
    }

    //查询所有cellCode
    private List<String> findAllCellCode() {
        return baseMapper.findAllCellCode();
    }

    //查询所有某ip下的灯位
    private List<Integer> findAllLedId(String ip) {
        return baseMapper.findAllLedId(ip);
    }

}




